﻿using System.Collections.Generic;
using System.Xml;
using static WorkFlow.Data.NodeConfig;

namespace WorkFlow.Data
{
    public enum MasterType
    {
        Start,
        End,
        Automation,
        WaitAutomation,
        Interface,
        DynamicConnector,
        LineArc,
        IsSubprocess,
        Other
    }
    public enum ConfigType
    {
        Aotumation,
        Interface,
        SubProcess,
        None

    }
    public class Parameter
    {

        public Parameter()
        {
        }
        public Parameter(string name, string value)
        {
            _Name = name;
            _Value = value;
        }
        string _Name;
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        string _Value;
        public string Value
        {
            get
            {
                return _Value;
            }
            set
            {
                _Value = value;
            }
        }
    }
    public class NodeConfig
    {
        ConfigType _ConfigType = ConfigType.None;
        public ConfigType ConfigType
        {
            get { return _ConfigType; }
            set { _ConfigType = value; }
        }

        string _TypeValue;
        public string TypeValue
        {
            get { return _TypeValue; }
            set { _TypeValue = value; }
        }

        List<Parameter> _InParameters;
        public List<Parameter> InParameters
        {
            get { return _InParameters; }
            set { _InParameters = value; }
        }
        List<Parameter> _OutParameters;
        public List<Parameter> OutParameters
        {
            get { return _OutParameters; }
            set { _OutParameters = value; }
        }
    }
    public class WorkFlowFile
    {
        string _StepID;
        public string StepID
        {
            get { return _StepID; }
            set { _StepID = value; }
        }

        string _StepName;
        public string StepName
        {
            get { return _StepName; }
            set { _StepName = value; }
        }

        NodeConfig _Config;
        public NodeConfig Config
        {
            get { return _Config; }
            set { _Config = value; }
        }

        int _RequestCount = 1;
        public int RequestRequestCount
        {
            get { return _RequestCount; }
            set { _RequestCount = value; }
        }

        string _TimeOut;
        public string TimeOut
        {
            get { return _TimeOut; }
            set { _TimeOut = value; }
        }

        MasterType _shapeType;
        public MasterType ShapeType
        {
            get { return _shapeType; }
            set { _shapeType = value; }
        }

        XmlNode _ShapeNode;
        public XmlNode ShapeNode
        {
            get { return _ShapeNode; }
            set
            {
                _ShapeNode = value;
                _Config = new NodeConfig();
                _Config.InParameters = new List<Parameter>();
                _Config.OutParameters = new List<Parameter>();
                XmlNodeList shapeItemNodes = value.ChildNodes;
                foreach (XmlNode configItemNode in shapeItemNodes)
                {
                    string nodeName = configItemNode.Name;
                    switch (nodeName)
                    {
                        case "Config":
                            SetNodeConfig(configItemNode);
                            break;
                        case "TimeOut":
                            _TimeOut = configItemNode.InnerText;
                            break;
                        case "RequestCount":
                            int.TryParse(configItemNode.InnerText, out _RequestCount);
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        private void SetNodeConfig(XmlNode configNode)
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml($"<root>{configNode.InnerText}</root>");
            // Config Details
            _Config = new NodeConfig();
            _Config.InParameters = new List<Parameter>();
            _Config.OutParameters = new List<Parameter>();
            XmlNodeList xmlNodeList = xmlDocument.FirstChild.ChildNodes;
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                if (xmlNode.Name == "In" || xmlNode.Name == "Out")
                {
                    // Add Config In or Out
                    List<Parameter> parameters = new List<Parameter>();
                    XmlNodeList filedNodes = xmlNode.ChildNodes;
                    foreach (XmlNode item in filedNodes)
                    {
                        Parameter parameter = new Parameter();
                        parameter.Name = item.Attributes["name"].Value;
                        parameter.Value = item.InnerText;
                        parameters.Add(parameter);
                    }

                    if (xmlNode.Name == "In")
                    {
                        _Config.InParameters = parameters;
                    }
                    else
                    {
                        _Config.OutParameters = parameters;
                    }
                }
                else
                {
                    switch (xmlNode.Name)
                    {
                        case "Service":
                            _Config.ConfigType = ConfigType.Aotumation;
                            _Config.TypeValue = xmlNode.Attributes["name"].Value;
                            break;
                        case "View":
                            _Config.ConfigType = ConfigType.Interface;
                            _Config.TypeValue = xmlNode.Attributes["name"].Value;
                            break;
                        case "SubProcess":
                            _Config.ConfigType = ConfigType.SubProcess;
                            _Config.TypeValue = xmlNode.Attributes["name"].Value;
                            break;
                        default:
                            break;
                    }

                }
            }

        }
    }
}
